#include "mymath.h"

float Matan(float rad)
{
    if (rad < 0)
        return -Matan(-rad);
    if (rad <= 0.25f){
        float ans = rad*(0.47831170583472860f * rad - 1.1679191357523431f);
        return ans*(0.29922976727874773f * ans - 0.85630501107017942f);
    }
    if (rad <= 0.75f)
        return 0.463647609f + Matan((rad - 0.5f) / (1.0f + rad*0.5f));
    if (rad <= 2.0f)
        return 0.8760580506f + Matan((rad - 1.2f) / (1.0f + rad*1.2f));
    return 1.3258186637f + Matan((rad - 4.0f) / (1.0f + rad * 4.0f));
}

float Matan2(float y,float x)
{
    if (x > 0)
        return Matan(y / x);
    if (x < 0)
        return (y >= 0) ? (Matan(y / x) + PI) : (Matan(y / x) - PI);
    return (y > 0) ? (PI / 2) : ((y < 0) ? (-PI / 2) : 0);
}

float Msqrt(float number)
{
    long i;
    float x, y;
    x = number * 0.5f;
    y = number;
    i = *(long *)&y;
    i = 0x5f3759df - (i >> 1);
    y = *(float *)&i;
    y = y * (1.5f - (x * y * y));
    y = y * (1.5f - (x * y * y));
    return number * y;
}

float Q_rsqrt(float number)
{
    long i;
    float x2, y;
    x2 = number * 0.5f;
    y  = number;
    i  = * ( long * ) &y;
    i  = 0x5f3759df - ( i >> 1 );
    y  = * ( float * ) &i;
    y  = y * ( 1.5f - ( x2 * y * y ) );
    y  = y * ( 1.5f - ( x2 * y * y ) );
    return y;
}

float Masin(float x)
{
    if(x<0)
        return -Masin(-x);
    else if(x<1.0f)
        return Matan(x*Q_rsqrt(1.0f-x*x));
    else
        return PI/2.0f;
}

float Msin(float rad)
{
    float ans;
    ans = rad*(1.27323954f - 0.405284735f * ABS(rad));
    ans = ans*(0.775f + 0.225f*ABS(ans));
    return ans;
}

float Mexp(float x)
{
    long i = (long)(x * 12102203 + 1064872507);
    return *(float*)&i;
}
